// @Title  请填写文件名称（需要改）
// @Description  请填写文件描述（需要改）
// @Author  请填写自己的真是姓名（需要改）  2021/2/23 21:06
// @Update  请填写自己的真是姓名（需要改）  2021/2/23 21:06
package error

import (
	"errors"
	"fmt"
	"os"
)

func CreateErr() {

	err1 := errors.New("math: square root of negative number")
	err2 := fmt.Errorf("math: square root of negative number %d", 33)
	/**
	通过fmt.Errorf函数，基于已经存在的err再生成一个新的newErr，然后附加上我们想添加的文本信息。
	这种办法比较方便，但是问题也很明显，我们丢失了原来的err，因为它已经被我们的fmt.Errorf函数转成一个新的字符串了。
	*/
	newErr := fmt.Errorf("数据上传问题: %v", err1)

	fmt.Println(err1, err2, newErr)

	/*
	判断newErr 是否是  err1
	如果err和target是同一个，那么返回true
	如果err 是一个wrap error,target也包含在这个嵌套error链中的话，那么也返回true。
	 */
	fmt.Println(errors.Is(err1,newErr))

	//获得被嵌套的error,err必须有  func Unwrap() error 方法,否则返回nil
	fmt.Println(errors.Unwrap(newErr))


	/**
	As所做的就是遍历err嵌套链，从里面找到类型符合的error，
	然后把这个error赋予target,这样我们就可以使用转换后的target了，
	这里有值得赋予，所以target必须是一个指针
	 */
	var perr *os.PathError
	if errors.As(err2, &perr) {
		fmt.Println(perr.Path)
	}

	fmt.Println(perr)//nil



}

// 只要实现了
//type error interface {
//	Error() string
//}
//接口就是 error
//
type MyError struct {
	msg string
}

func (err *MyError) Error() string {
	return err.msg
}

func RunMyError() {
	e := MyError{
		msg: " error ",
	}

	fmt.Println(e)




}


